#ifndef INC_CAMERA_H
#define INC_CAMERA_H

#include "Polygon.h"
#include "Vector.h"
#include "Matrix.h"
#include "Output.h"
#include "Color.h"
#include "Point.h"
#include "Buffer.h"
#include "Line.h"
/*********************************************/
class Camera
{
private:
	// Data members
	CMatrix::CMatrix<fl64>		viewingTransformation;		// viewingtransformation matrix
	CVector::CVector<fl64>		wu, wl, vu, vl;			// window to viewport transformation
	IBaseOutput*			output;				// Output Class
	static uint32			newCamID;			// The id number to use when creating a new camera
	static uint32			camCount;			// The number of currently active cameras
	uint32				camID;				// This cameras identifier
	
	// Methods
	inline void projectPoint3D( Point3D& p ) const;
	inline void winToView( Point3D& p ) const;
	void viewTransform( Point3D& p ) const;
	void initScalingTransformation( const uint32& width, const uint32& height );
	void activateCamera() const;
	Color getFSAAPixelSample( const uint32&, const uint32& ) const;

protected:
	// Construction & Destruction
	Camera(const Camera&) {};					// It's not allowed to copy cameras
	void operator=(const Camera&) {};				// again no camera assignments/copies allowed for stability purposes
	
public:	
	// Control Methods
	void flush( const uint32 buffer ) const;					// flushes a camera buffer to it's output
	void clear( const uint32 buffer );						// clears a camera buffer
	uint32 getID() const;								// Returns the camera identifier
	void setViewParameters( const Point3D& eye, const Point3D& view );		// Eye/View point change

	// Drawing Methods
	void drawPolygon3D( const Polygon& p );				// Draw a Polygon after 3D transformations
	void drawPolygon2D( const Polygon& p );				// Draw a Polygon without 3D transformations ( = Sprite )
	void drawLine3D( const Line3D& );				// Draw a line after camera transformations
	void drawLine2D( const Line3D& );				// Draw a line without camera transformations
	void drawPoint3D( const Point3D& );				// Draw a point after 3D transformations
	void drawPoint2D( const Point3D& );				// Draw a 2D point ( 1 pixel wide )
	void drawPoint2D( const Point3D&, const uint16 );		// Draw a dot
	
	// Construction & Destruction
	Camera( IBaseOutput*);
	~Camera();
};
/*********************************************/
#endif // INC_CAMERA_H